#include "qtdbusproperties.h"

#include "qtdbusobjectmanager.h"
#include "private/qtdbusobjectmanager_p.h"

#include <QMetaObject>
#include <QDBusMessage>
#include <QMetaProperty>
#include <QDBusMetaType>

QtDBusProperties::QtDBusProperties(QtDBusObjectManager *parent) : QObject{parent}, QDBusContext{}
{
}

QVariantMap QtDBusProperties::propertiesOf(const QObject *object)
{
    if (!object)
        return {};
    const QMetaObject *metaObject = object->metaObject();
    static const int start = QObject::staticMetaObject.propertyCount();
    int position = metaObject->propertyCount();
    QVariantMap properties;
    while (position >= start) {
        --position;
        const QMetaProperty &property = metaObject->property(position);
#if QT_VERSION_MAJOR < 6
        if (!QDBusMetaType::typeToSignature(property.userType()))
#else
        if (!QDBusMetaType::typeToSignature(property.metaType()))
#endif
            continue;
        properties[property.name()] = property.read(object);
    }
    return properties;
}

QDBusVariant QtDBusProperties::Get(const QString &interface, const QString &property)
{
    QObject *object = objectAt(interface);
    return QDBusVariant{object->property(property.toUtf8())};
}

void QtDBusProperties::Set(const QString &interface, const QString &property, const QDBusVariant &value)
{
    QObject *object = objectAt(interface);
    object->setProperty(property.toUtf8(), value.variant());
}

QVariantMap QtDBusProperties::GetAll(const QString &interface)
{
    return propertiesOf(objectAt(interface));
}

QObject *QtDBusProperties::objectAt(const QString &interface) const
{
    return static_cast<QtDBusObjectManager *>(parent())->objectAt(message().path(), interface);
}
